from flask import Blueprint, jsonify, request, send_file, render_template
import pandas as pd
import numpy as np
from pathlib import Path
import os
import sys
import traceback
from entertainment_outside_analysis import main as analyze_entertainment

# 创建蓝图
entertainment_bp = Blueprint('entertainment', __name__, url_prefix='/entertainment')

def get_resource_path(relative_path):
    """获取资源文件的绝对路径，支持开发环境和打包环境"""
    if hasattr(sys, '_MEIPASS'):
        # PyInstaller 打包环境
        base_path = sys._MEIPASS
    else:
        # 开发环境
        base_path = os.path.dirname(os.path.abspath(__file__))
    
    return os.path.join(base_path, relative_path)

# 配置数据文件路径
DATA_DIR = Path("data")
ALLDATA_DIR = DATA_DIR / "alldata"
MISMATCH_FILE = ALLDATA_DIR / "地址不匹配数据.xlsx"

# 确保目录存在
ALLDATA_DIR.mkdir(parents=True, exist_ok=True)

@entertainment_bp.route('/')
def index():
    """管辖范围外业务招待费分析页面"""
    return render_template('pages/entertainment.html', active_page='entertainment')

@entertainment_bp.route('/check-result-file')
def check_result_file():
    """检查分析结果文件是否存在"""
    try:
        exists = MISMATCH_FILE.exists()
        return jsonify({'exists': exists})
    except Exception as e:
        return jsonify({
            'error': f'检查文件时出错: {str(e)}'
        }), 500

@entertainment_bp.route('/generate-analysis', methods=['POST'])
def generate_entertainment_analysis():
    """生成管辖范围外业务招待费分析结果"""
    try:
        # 调用分析函数生成结果
        success = analyze_entertainment()
        if not success:
            return jsonify({
                'success': False,
                'error': '分析过程出现错误'
            })
        return jsonify({'success': True})

    except Exception as e:
        print(f"生成分析结果时出错: {str(e)}")
        traceback.print_exc()
        return jsonify({
            'success': False,
            'error': f'生成分析结果时出错: {str(e)}'
        })

@entertainment_bp.route('/get-data', methods=['POST'])
def get_entertainment_data():
    """获取管辖范围外业务招待费分析数据"""
    try:
        if not MISMATCH_FILE.exists():
            return jsonify({
                'error': '请先执行数据分析'
            }), 400

        try:
            df = pd.read_excel(MISMATCH_FILE, engine='openpyxl')
            # 确保业务类型列为字符串类型
            if '业务类型' in df.columns:
                df['业务类型'] = df['业务类型'].astype(str).str.zfill(4)
        except Exception as e:
            return jsonify({
                'error': f'读取Excel文件失败: {str(e)}'
            }), 400

        if df.empty:
            return jsonify({
                'error': '分析结果为空'
            }), 400

        # 获取所有列名
        all_columns = df.columns.tolist()

        # 获取筛选参数
        data = request.get_json()
        get_all = data.get('all', False)

        if get_all:
            result_data = df.to_dict('records')
        else:
            page = int(data.get('page', 1))
            per_page = 20
            start_idx = (page - 1) * per_page
            end_idx = start_idx + per_page
            
            result_data = df.iloc[start_idx:end_idx].to_dict('records')

        # 处理数据中的特殊值
        for record in result_data:
            for key, value in record.items():
                if pd.isna(value):
                    record[key] = None
                elif key == '业务类型':  # 对业务类型列特殊处理
                    record[key] = str(value).zfill(4)
                elif isinstance(value, (np.int64, np.float64)):
                    record[key] = float(value) if isinstance(value, np.float64) else int(value)

        return jsonify({
            'success': True,
            'data': result_data,
            'all_columns': all_columns,
            'total_records': len(df)
        })

    except Exception as e:
        traceback.print_exc()
        return jsonify({
            'success': False,
            'error': f'获取数据时出错: {str(e)}'
        }), 500

@entertainment_bp.route('/download-excel')
def download_excel():
    """下载分析结果"""
    try:
        if not MISMATCH_FILE.exists():
            return jsonify({
                'error': '分析结果文件不存在'
            }), 404

        # 读取Excel文件
        df = pd.read_excel(MISMATCH_FILE)
        
        # 确保业务类型列为字符串类型并填充为4位
        if '业务类型' in df.columns:
            df['业务类型'] = df['业务类型'].astype(str).str.zfill(4)
        
        # 获取筛选条件
        selected_fields = request.args.getlist('fields')
        risk_level_1 = request.args.get('risk_level_1') == 'true'
        risk_level_2 = request.args.get('risk_level_2') == 'true'
        match_status = request.args.getlist('match_status')

        # 应用筛选条件
        if risk_level_1 or risk_level_2 or match_status:
            conditions = []
            
            # 风险等级筛选
            if risk_level_1 or risk_level_2:
                risk_conditions = []
                if risk_level_1:
                    risk_conditions.append(df['风险等级'] == '一级')
                if risk_level_2:
                    risk_conditions.append(df['风险等级'] == '二级')
                conditions.append(pd.concat(risk_conditions, axis=0))
            
            # 地址匹配状态筛选
            if match_status:
                match_conditions = [df['地址匹配状态'] == status for status in match_status]
                conditions.append(pd.concat(match_conditions, axis=0))
            
            # 合并所有条件
            if conditions:
                final_condition = pd.concat(conditions, axis=1).all(axis=1)
                df = df[final_condition]
        
        # 如果指定了字段，只保留选择的字段
        if selected_fields:
            valid_fields = [field for field in selected_fields if field in df.columns]
            if not valid_fields:
                return jsonify({
                    'error': '没有找到有效的字段'
                }), 400
            df = df[valid_fields]
            
            # 如果筛选后还包含业务类型列，确保其格式正确
            if '业务类型' in valid_fields:
                df['业务类型'] = df['业务类型'].astype(str).str.zfill(4)

        # 如果数据为空，返回错误
        if df.empty:
            return jsonify({
                'error': '筛选后没有符合条件的数据'
            }), 400

        # 创建临时文件名，使用时间戳确保唯一性
        from datetime import datetime
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        filename = f"地址不匹配数据_{timestamp}.xlsx"
        
        # 创建临时目录用于存放下载文件
        temp_dir = Path(get_resource_path('temp'))
        temp_dir.mkdir(parents=True, exist_ok=True)
        temp_file = temp_dir / filename
        
        try:
            # 保存筛选后的数据到临时文件
            with pd.ExcelWriter(temp_file, engine='openpyxl', mode='w') as writer:
                df.to_excel(writer, index=False)
                # 设置业务类型列为文本格式
                if '业务类型' in df.columns:
                    worksheet = writer.sheets['Sheet1']
                    for idx, col in enumerate(df.columns):
                        if col == '业务类型':
                            # 设置整列为文本格式
                            col_letter = chr(65 + idx)  # 将列索引转换为Excel列字母
                            worksheet.column_dimensions[col_letter].number_format = '@'
                            # 设置每个单元格为文本格式
                            for row in range(2, len(df) + 2):  # Excel是1-based，第一行是标题
                                cell = worksheet.cell(row=row, column=idx + 1)
                                cell.number_format = '@'  # 设置单元格格式为文本
                                # 确保单元格的值是字符串格式
                                cell.value = str(cell.value).zfill(4)
            
            response = send_file(
                temp_file,
                as_attachment=True,
                download_name=filename,
                mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
            )
            
            # 设置回调以在发送后删除临时文件
            @response.call_on_close
            def cleanup():
                try:
                    if temp_file.exists():
                        temp_file.unlink()
                except Exception as e:
                    print(f"清理临时文件时出错: {str(e)}")
            
            return response
            
        except Exception as e:
            # 如果出错，确保清理临时文件
            if temp_file.exists():
                try:
                    temp_file.unlink()
                except:
                    pass
            return jsonify({
                'error': f'保存文件时出错: {str(e)}'
            }), 500

    except Exception as e:
        print(f"下载文件时出错: {str(e)}")
        traceback.print_exc()
        return jsonify({
            'error': f'下载文件时出错: {str(e)}'
        }), 500 